package com.ytd.common.util;

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

public class RSAUtils {
    /**
     * 算法
     */
    public static final String KEY_ALGORITHM = "RSA";
    /**
     * 公钥
     */
    private static final String PUBLIC_KEY = "RSAPublicKey";
    /**
     * 私钥
     */
    private static final String PRIVATE_KEY = "RSAPrivateKey";
    /**
     * RSA密钥长度
     * 默认1024位
     * 密钥长度必须位64的倍数
     * 范围在512-65536之间
     */
    private static final int KEY_SIZE = 512;

    /**
     * 初始化密钥
     *
     * @return 密钥Map
     */
    public static Map<String, Object> initKey() {
        try {
            // 实例化密钥对生成器
            KeyPairGenerator gen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            // 初始化密钥对生成器
            gen.initialize(KEY_SIZE);
            // 生成密钥对
            KeyPair keyPair = gen.generateKeyPair();
            // 公钥
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            // 私钥
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 封装密钥
            Map<String, Object> map = new HashMap<String, Object>(2);
            map.put(PUBLIC_KEY, rsaPublicKey);
            map.put(PRIVATE_KEY, rsaPrivateKey);
            return map;
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 取得公钥
     *
     * @param map
     * @return
     */
    public static byte[] getPublicKey(Map<String, Object> map) {
        Key key = (Key) map.get(PUBLIC_KEY);
        return key.getEncoded();
    }

    /**
     * 取得公钥
     *
     * @param map
     * @return
     */
    public static byte[] getPrivateKey(Map<String, Object> map) {
        Key key = (Key) map.get(PRIVATE_KEY);
        return key.getEncoded();
    }

    /**
     * 私钥解密
     *
     * @param data 待解密数据
     * @param key 私钥
     * @return byte[] 解密数据
     */
    public static String decryptByPrivateKey(byte[] data, byte[] key) {
        try {
            //取得私钥
            PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            //生成私钥
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs);
            //对数据解密
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return new String(cipher.doFinal(data), "utf-8");
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 公钥解密
     *
     * @param data
     * @param key
     * @return
     */
    public static byte[] decryptByPublicKey(byte[] data, byte[] key) {
        try {
            //取得公钥
            X509EncodedKeySpec pkcs = new X509EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            //生成公钥
            PublicKey publicKey = keyFactory.generatePublic(pkcs);
            //对数据解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            return cipher.doFinal(data);
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 公钥加密
     *
     * @param data
     * @param key
     * @return
     */
    public static String encryptByPublicKey(byte[] data, byte[] key) {
        try {
            //取得公钥
            X509EncodedKeySpec pkcs = new X509EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            //生成公钥
            PublicKey publicKey = keyFactory.generatePublic(pkcs);
            //对数据加密
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return WTBase64.encode(cipher.doFinal(data));
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 私钥加密
     *
     * @param data
     * @param key
     * @return
     */
    public static byte[] encryptByPrivateKey(byte[] data, byte[] key) {
        try {
            //取得私钥
            PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            //生成公钥
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs);
            //对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
        }
        return null;
    }


}
